#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define STACK_SIZE 10
#define N 20
/* external variables */
int contests[STACK_SIZE];
int top = 0;
void static_overflow(void) {
    printf("Expression is too complex.\n");
    exit(EXIT_FAILURE);
}
void stack_underflow(void) {
    printf("Not enough operands in expression.\n");
    exit(EXIT_FAILURE);
}
void make_empty(void) {
    top = 0;
}
bool is_empty(void) {
    return top == 0;
}
bool is_full(void) {
    return top == STACK_SIZE;
}
void push(int i) {
    if (is_full())
        static_overflow();
    else
        contests[top++] = i;
}
int pop(void) {
    if (is_empty())
        stack_underflow();
    else
        return contests[--top];
}
void calculate(char method);
int evaluate_RPN_expression(const char *expression);
int main(void)
{
    printf("Enter an RPN expression: ");
    int ch, i = 0;
    char exp[N+1];
    while((ch = getchar()) != '\n' && ch != EOF)
        if (i < N)
            exp[i++] = ch;
    exp[i] = '\0';
    printf("Value of expression: %d\n", evaluate_RPN_expression(exp));
    return 0;
}
void calculate(char method) {
    int x, y;
    y = pop();
    x = pop();
    switch (method)
    {
    case '+':
        push(x + y);
        break;
    case '-':
        push(x - y);
        break;
    case '*':
        push(x * y);
        break;
    case '/':
        push(x / y);
        break;
    }
}
int evaluate_RPN_expression(const char *expression) {
    for (const char *p = expression; *p; p++) {
        switch (*p)
        {
        case '0': push(0); break;
        case '1': push(1); break;
        case '2': push(2); break;
        case '3': push(3); break;
        case '4': push(4); break;
        case '5': push(5); break;
        case '6': push(6); break;
        case '7': push(7); break;
        case '8': push(8); break;
        case '9': push(9); break;
        case '+': case '-': case '*': case '/':
            calculate(*p);
            break;
        }
    }
    int res = pop();
    make_empty();
    return res;
}
